Skip to content

Retrieve the latest kindest/node image for tests#1120

Open
joaopapereira wants to merge 1 commit into
carvel-dev:developfrom
joaopapereira:change-tests
Open

Retrieve the latest kindest/node image for tests#1120
joaopapereira wants to merge 1 commit into
carvel-dev:developfrom
joaopapereira:change-tests

Conversation

@joaopapereira

Copy link
Copy Markdown
Member

What this PR does / why we need it:

After talking with Release team of K8s they told me that they do not always create images for every version of k8s. In this PR we are changing our logic to retrieve the latest publish image of kindest/node from docker hub itself.

As part of the change we are also adding a warning, because now these 2 versions are decoupled, whenever a new minor of k8s is released and they do not publish a new kindest/node image, we write a warning in the output.

Does this PR introduce a user-facing change?

None

Additional Notes for your reviewer:

Review Checklist:
  • Follows the developer guidelines
  • Relevant tests are added or updated
  • Relevant docs in this repo added or updated
  • Relevant carvel.dev docs added or updated in a separate PR and there's
    a link to that PR
  • Code is at least as readable and maintainable as it was before this
    change

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the CI workflow to determine the latest Kubernetes version used for tests by querying Docker Hub for the newest kindest/node image tag, and emits a warning when kind images lag behind upstream Kubernetes releases.

Changes:

  • Resolve latest test version from Docker Hub kindest/node tags rather than GitHub Kubernetes releases.
  • Add a warning when the latest kind image minor version is behind the upstream Kubernetes latest minor.
  • Simplify kind cluster creation to always use kindest/node:${k8s_version}.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/test-gh.yml Outdated
Comment on lines +30 to +33
k8s_version=$(curl -s "https://hub.docker.com/v2/repositories/kindest/node/tags?page_size=100&ordering=last_updated" \
| grep -oE '"name":"v[0-9]+\.[0-9]+\.[0-9]+"' \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' \
| sort -V | tail -1)

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Docker Hub request only fetches the first page (page_size=100) ordered by last_updated, then picks the highest semver from that subset. If the highest kindest/node tag isn’t in the most-recently-updated 100 tags, this can resolve to an older Kubernetes version. Consider paginating until exhaustion (following the next link) or using an API query that guarantees you’re considering all version tags (e.g., ordering by name and iterating pages) before selecting the max.

Suggested change
k8s_version=$(curl -s "https://hub.docker.com/v2/repositories/kindest/node/tags?page_size=100&ordering=last_updated" \
| grep -oE '"name":"v[0-9]+\.[0-9]+\.[0-9]+"' \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' \
| sort -V | tail -1)
url="https://hub.docker.com/v2/repositories/kindest/node/tags?page_size=100&ordering=last_updated"
all_tags=""
while [ -n "$url" ]; do
response=$(curl -s "$url")
# Collect all semver tags from this page
page_tags=$(printf '%s\n' "$response" \
| grep -oE '"name":"v[0-9]+\.[0-9]+\.[0-9]+"' \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')
if [ -n "$page_tags" ]; then
all_tags="${all_tags}"$'\n'"${page_tags}"
fi
# Follow pagination via the "next" field; it is either a URL or null
next_url=$(printf '%s\n' "$response" | grep -oE '"next":[^,]*' | sed -E 's/"next":(null|"([^"]*)")/\2/')
if [ -z "$next_url" ]; then
url=""
else
url="$next_url"
fi
done
k8s_version=$(printf '%s\n' "$all_tags" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+' | sort -V | tail -1)

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/test-gh.yml Outdated
Comment on lines +30 to +38
k8s_version=$(curl -s "https://hub.docker.com/v2/repositories/kindest/node/tags?page_size=100&ordering=last_updated" \
| grep -oE '"name":"v[0-9]+\.[0-9]+\.[0-9]+"' \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' \
| sort -V | tail -1)
echo "Resolved latest kindest/node version to: $k8s_version"

# Warn if kind's latest minor version lags behind the latest upstream Kubernetes minor version
k8s_latest=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/kubernetes/kubernetes/releases/latest \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curl -s will succeed even on HTTP errors, and if the grep/sort pipeline finds no matching tags, k8s_version becomes empty. That will later cause kind create cluster --image kindest/node: to fail with a confusing error (and the minor-version comparison may emit “integer expression expected”). Consider using curl -fsSL (and/or retries) and explicitly validating that k8s_version and k8s_latest are non-empty before continuing; otherwise exit 1 with a clear message.

Suggested change
k8s_version=$(curl -s "https://hub.docker.com/v2/repositories/kindest/node/tags?page_size=100&ordering=last_updated" \
| grep -oE '"name":"v[0-9]+\.[0-9]+\.[0-9]+"' \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' \
| sort -V | tail -1)
echo "Resolved latest kindest/node version to: $k8s_version"
# Warn if kind's latest minor version lags behind the latest upstream Kubernetes minor version
k8s_latest=$(curl -Ls -o /dev/null -w %{url_effective} https://github.com/kubernetes/kubernetes/releases/latest \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')
k8s_version=$(curl -fsSL "https://hub.docker.com/v2/repositories/kindest/node/tags?page_size=100&ordering=last_updated" \
| grep -oE '"name":"v[0-9]+\.[0-9]+\.[0-9]+"' \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' \
| sort -V | tail -1)
if [ -z "$k8s_version" ]; then
echo "::error::Failed to resolve latest kindest/node version from Docker Hub."
exit 1
fi
echo "Resolved latest kindest/node version to: $k8s_version"
# Warn if kind's latest minor version lags behind the latest upstream Kubernetes minor version
k8s_latest=$(curl -fsSL -o /dev/null -w '%{url_effective}' https://github.com/kubernetes/kubernetes/releases/latest \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+')
if [ -z "$k8s_latest" ]; then
echo "::error::Failed to resolve latest upstream Kubernetes version from GitHub releases."
exit 1
fi

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/test-gh.yml Outdated
Comment on lines +31 to +32
| grep -oE '"name":"v[0-9]+\.[0-9]+\.[0-9]+"' \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' \

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Docker Hub response is JSON, but it’s being parsed with grep. This is brittle (formatting/escaping changes can break it) and can accidentally match unrelated "name" fields. Prefer parsing the JSON with a proper tool available on GitHub-hosted runners (e.g., jq -r '.results[].name' or a small python -c JSON parser) and then apply the semver selection on those values.

Suggested change
| grep -oE '"name":"v[0-9]+\.[0-9]+\.[0-9]+"' \
| grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' \
| jq -r '.results[].name' \
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/test-gh.yml Outdated
echo "k8s_version=$k8s_version" >> $GITHUB_ENV
- name: Create Kind Cluster(k8s version ${{ env.k8s_version }})
echo "k8s_version=${k8s_version}" >> $GITHUB_ENV
- name: Create Kind Cluster (k8s version ${{ env.k8s_version }})

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

${{ env.k8s_version }} in the step name won’t be populated by values written to $GITHUB_ENV at runtime (those affect the shell environment, not the expression env context). If you want the resolved version in the step name, emit it as a step output and reference steps.resolve-k8s-version.outputs..., or keep the name static and just echo the chosen version in the step logs.

Suggested change
- name: Create Kind Cluster (k8s version ${{ env.k8s_version }})
echo "k8s_version=${k8s_version}" >> "$GITHUB_OUTPUT"
- name: Create Kind Cluster (k8s version ${{ steps.resolve-k8s-version.outputs.k8s_version }})

Copilot uses AI. Check for mistakes.
After talking with Release team of K8s they told me that they do not
always create images for every version of k8s. In this PR we are
changing our logic to retrieve the latest publish image of kindest/node
from docker hub itself.

As part of the change we are also adding a warning, because now these 2
versions are decoupled, whenever a new minor of k8s is released and they
do not publish a new kindest/node image, we write a warning in the
output.

Signed-off-by: Joao Pereira <joaopapereira@gmail.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants